package com.barry.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.barry.ExcelGenerator;
import com.barry.bean.OperationData;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @ClassName GenReportUtil
 * @Description 报表生成工具
 * @Author wangxuexing
 * @Date 2020/2/21 15:43
 * @Version 1.0
 */
public class GenReportUtil {
    private static Lock lock = new ReentrantLock();
    /**
     * 根据数据及模板生成报表
     * @param dataList 数据列表
     * @param templateFileName 模板路径
     * @param outputStream 生成文件路径
     * @param <T> 数据对象
     */
    public static <T> void genReportByDataByTemplate(List<List<T>> dataList,
                                                     String templateFileName,
                                                     OutputStream outputStream,
                                                     String sheetName){
        InputStream templateInputStream = FileUtil.getInputStream(templateFileName);
        ExcelWriter excelWriter = EasyExcel.write(outputStream, OperationData.class)
                .withTemplate(templateInputStream).needHead(false)
                /*.registerWriteHandler(new MyRowWriteHandler())*/.build();
        // 这里注意 如果同一个sheet只要创建一次
        WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
        // 去调用写入,这里我调用了五次，实际使用时根据数据库分页的总的页数来
        for (int i = 0; i < dataList.size(); i++) {
            // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
            List<T> data = dataList.get(i);
            write(excelWriter, data, writeSheet);
        }
        //千万别忘记finish 会帮忙关闭流
        excelWriter.finish();
    }

    public static <T> void genReportByData(List<List<T>> dataList,
                                                     String templateFileName,
                                                     OutputStream outputStream,
                                                     String sheetName){
        InputStream templateInputStream = FileUtil.getInputStream(templateFileName);
        ExcelWriter excelWriter = EasyExcel.write(outputStream, OperationData.class)
                .withTemplate(templateInputStream).needHead(false)
                /*.registerWriteHandler(new MyRowWriteHandler())*/.build();
        // 这里注意 如果同一个sheet只要创建一次
        WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
        // 去调用写入,这里我调用了五次，实际使用时根据数据库分页的总的页数来
        for (int i = 0; i < dataList.size(); i++) {
            // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
            List<T> data = dataList.get(i);
            write(excelWriter, data, writeSheet);
        }
        //千万别忘记finish 会帮忙关闭流
        excelWriter.finish();
    }

    /**
     * 线程安全写入数据
     * @param excelWriter
     * @param data
     * @param writeSheet
     * @param <T>
     */
    private static <T> void write(ExcelWriter excelWriter, List<T> data, WriteSheet writeSheet){
        lock.lock();
        try{
            excelWriter.write(data, writeSheet);
            data = null;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws Exception {
        genReportDerictory();
    }

    public static void genReportDerictory() throws Exception {
        List<List<OperationData>> data = ExcelGenerator.genData();
        File file = File.createTempFile("downloadFileName", ".xlsx");
        try(OutputStream outputStream = new FileOutputStream(file)) {
            GenReportUtil.genReportByDataByTemplate(data,
                    "operation_data.xlsx",
                    outputStream,
                    "经营数据");
        }
    }
}
